#include "UapStateConnected.h"
#include "UapStateMap.h"
#include "ClientUapProxy.h"
#include "MgwGapProxy.h"
#include "MediaLibrary.h"
#include "Trace.h"

namespace tsc
{
namespace sgw
{

using namespace tsc::common;

/*******************************************************************************
 *
 * Constructor
 *
 ******************************************************************************/
UapStateConnected::UapStateConnected() :
	UapStateBase("Connected")
{

} // UapStateConnected::UapStateConnected

/*******************************************************************************
 *
 * Destructor
 *
 ******************************************************************************/
UapStateConnected::~UapStateConnected()
{

} // UapStateConnected::~UapStateConnected


UapStateConnected* UapStateConnected::instance()
{
	static UapStateConnected mInstance;
	return &mInstance;
}

//===================================================================
void
UapStateConnected::handleEventUapConnectionReleaseReq(
    UapGenerator* uapGen,
    UapEventConnectionReleaseReq* event,
    EventData*& eventData)
{
    TRACE(3, STR("UapConnRel received - deleting UapGenerator, connId=0x%x",
                 uapGen->getConnectionId()));

    delete uapGen;
    uapGen = 0;

    EventData::deleteEvent(eventData);
}

//===================================================================
void
UapStateConnected::handleEventUapMediaBearerSetupReq(
    UapGenerator* uapGen,
    UapEventMediaBearerSetupReq* event,
    EventData*& eventData)
{
    TRACE(3, STR("MediaBearerSetupReq received, connId=0x%x, mediaId=%u, "
                 "clientMediaPort=%u",
                 uapGen->getConnectionId(),
                 event->getMediaItemId(),
                 event->getClientMediaPort()));

    if(!MediaLibrary::instance().itemExists(event->getMediaItemId()))
    {
        TRACE(3, STR("MediaItem with id=%u not found - sending UapMediaBearerSetupRej, "
                     "connId=0x%x",
                     event->getMediaItemId(),
                     uapGen->getConnectionId()));

        // media item not found, send reject
        if(!ClientUapProxy::instance().sendUapMediaBearerSetupRej(
                uapGen->getConnectionId(),
                UserApplicationPart::CAUSE_MEDIA_NOT_AVAILABLE))
        {
            TRACE(1, STR("Failed to send MediaBearerSetupRej, connId=0x%x",
                         uapGen->getConnectionId()));
        }
    }
    else
    {
        uapGen->setClientMediaPort(event->getClientMediaPort());
        uapGen->setMediaItemId(event->getMediaItemId());

        if(MgwGapProxy::instance().sendGapMediaBearerSetupReq(
                uapGen->getConnectionId(),
                uapGen->getContext()->getClientIpAddress(),
                uapGen->getClientMediaPort(),
                uapGen->getMediaItemId()))
        {
            TRACE(3, STR("Sent GAP MediaBearerSetupReq to MGW, connId=0x%x",
                         uapGen->getConnectionId()));
            uapGen->startT643();
            uapGen->changeState(UapStateMap::mStateMediaBearerSetupPend);
        }
        else
        {
            TRACE(1, STR("Failed to send GAP MediaBearerSetupReq to MGW, sending"
                         "UapMediaBearerSetupRej to the client, connId=0x%x",
                         uapGen->getConnectionId()));

            // clear values stored in generator
            uapGen->setClientMediaPort(0);
            uapGen->setMediaItemId(MediaLibrary::INVALID_MEDIA_ITEM_ID);

            // and send reject to user client
            if(!ClientUapProxy::instance().sendUapMediaBearerSetupRej(
                    uapGen->getConnectionId(),
                    UserApplicationPart::CAUSE_UNSPECIFIED))
            {
                // bugger
                TRACE(1, STR("Failed to send UapMediaBearerSetupRej, connId=0x%x",
                             uapGen->getConnectionId()));
            }
        }

    }
    EventData::deleteEvent(eventData);
}


} // namespace sgw
} // namespace tsc
